#include "SocketClient.h"

void SocketClient::run()
{
    int i_sock = socket( AF_INET,SOCK_STREAM, 0);
    struct sockaddr_in con_server_addr;
    con_server_addr.sin_family = AF_INET;
    con_server_addr.sin_port = htons(5000);
    con_server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //连接
    while( connect(i_sock , (struct sockaddr *)&con_server_addr,sizeof(con_server_addr)) < 0 )
    {
        perror("reconnection...");
        sleep(2);
    }

    b_run = true;


    vector<string> vec_temp;
    while(b_run)
    {
        vec_temp.clear();
        //show menu
        if( i_menu == 0) // enter
        {
            EnterMenu();
            cin >> i_input;
            switch (i_input)
            {
            case 1:{
                /* login */
                // cookie login
                string str_cookie = ReadFile("cookie");
                int i_pos = str_cookie.find(":");
                if( str_cookie != "" && i_pos!= 0)
                {
                    Split(str_cookie,':',vec_temp);
                    string str_send = "type=log&username="+ vec_temp[0] +"&password=&cookie=" +  vec_temp[1];
                    // SEND(i_sock,str_send);
                    // //
                    // memset(buff,0,sizeof(buff));
                    // int i_len = RECV(i_sock,buff);
                    // string str_recv(buff);
                    string str_recv = request(i_sock,str_send);
                    
                    cout << GetValueBuUrl(str_recv, "msg") << endl;
                    if( GetValueBuUrl(str_recv, "code") == "0" ) //succ
                    {
                        b_login = true;
                        i_menu = 1; //main
                        break;
                    }
                }
                //username password login
                string str_u , str_p;

                cout << "<username>:" ;
                cin >> str_u;
                cout << "<password>:";
                cin >> str_p;
                if( str_u.empty() || str_p.empty())
                {
                    cout << "can not empty " << endl;
                    break;
                }
                
                string str_send = "type=log&username="+ str_u +"&password="+ str_p+"&cookie=";
                // SEND(i_sock,str_send);
                //     //
                // memset(buff,0,sizeof(buff));
                // int i_len = RECV(i_sock,buff);
                // string str_recv(buff);
                string str_recv = request(i_sock,str_send);
                   // cout << str_recv << endl;
                string str_tmp = GetValueBuUrl(str_recv, "msg") ;
                
                if( GetValueBuUrl(str_recv, "code") == "0") //succ
                {
                    b_login = true;
                    i_menu = 1; //main
                    
                    SaveFile("cookie",str_tmp);
                    cout << "登录成功" << endl;
                }else
                {
                    cout << str_tmp << endl;
                }

                break;
            }
            case 2:{
                /*register*/
                string str_u , str_p;

                cout << "<username>:" ;
                cin >> str_u;
                cout << "<password>:";
                cin >> str_p;
                if( str_u.empty() || str_p.empty())
                {
                    cout << "can not empty " << endl;
                    break;
                }
                string str_send =  "type=reg&username="+ str_u+"&password=" +str_p;
                // SEND(i_sock,str_send);

                // memset(buff,0,sizeof(buff));
                // cout << "register ing ...." << endl;
                // int i_len = RECV(i_sock,buff);
                // string str_recv(buff);
                string str_recv = request(i_sock,str_send);
            
                string str_tmp = GetValueBuUrl(str_recv, "msg") ;
                cout << str_tmp << endl;
                break;
            }
            case 3:{
                //exit
                stop();
                break;
            }
            default:
                cout << "input invaild!" << endl;
                break;
            }
        }else if( i_menu == 1 && b_login) //main
        {
            MainMenu();
            cin >> i_input;
            switch (i_input)
            {
                case 1:{
                    //get username
                    string str_send = "type=get&param=USERLIST";
                    // SEND(i_sock,str_send);

                    // memset(buff,0,sizeof(buff));
                    // int i_len = RECV(i_sock,buff);
                    // string str_recv(buff);
                    string str_recv = request(i_sock,str_send);

                    if( GetValueBuUrl(str_recv, "code") == "0")
                    {
                        // p2p enter
                       // i_menu = 2;
                    }
                    cout << GetValueBuUrl(str_recv, "msg") << endl;
                    cout << "输入对方用户名 :" ;
                    string str_taru = "";
                    cin >> str_taru;
                    
                    //
                    b_chat = true;
                    thread t_rec(&SocketClient::chatRecv,this,i_sock);
                    thread t_send(&SocketClient::chatSend,this,i_sock,str_taru);
                    t_rec.join();
                    t_send.join();
                    b_chat = false;
                    cout << "chat quit" << endl;
                    break;
                };
                case 2:{
                    //group
                    //get group list
                    
                    i_menu = 2;
                    b_gchat = true;
                    
                    break;
                };
                case 3:{
                    stop();
                    break;
                };
                default:{
                    cout << "input invaild!" << endl;
                    break;
                };
            }
        }
        else if( i_menu == 2 && b_login ) //group  1.create 2.get 3.join 4.exit"
        {
            GroupMenu();
            cin >> i_input;
            switch (i_input)
            {
                case 1:{
                    //crearte
                    string str_send = "type=ght&param=create&c=";
                    /*
                    SEND(i_sock,str_send);

                    memset(buff,0,sizeof(buff));
                    int i_len = RECV(i_sock,buff);
                    string str_recv(buff);
                    */
                   string str_recv = request(i_sock,str_send);
                     string str_retmsg = GetValueBuUrl(str_recv, "msg");
                   
                        // p2p enter
                       // i_menu = 2;
                    cout << "create success gid:" << str_retmsg << endl;
                    
                    
                    break;
                };
                case 2:{
                    //get username
                    string str_send = "type=ght&param=get&c=";
                    
                    /*
                    SEND(i_sock,str_send);

                    memset(buff,0,sizeof(buff));
                    int i_len = RECV(i_sock,buff);
                    string str_recv(buff);
                    */
                    string str_recv = request(i_sock,str_send);
                     string str_retmsg = GetValueBuUrl(str_recv, "msg");
                    
                        // p2p enter
                       // i_menu = 2;
                       cout << str_retmsg << endl;
                    
                    
                    break;
                };
                case 3:{
                    //join
                    string str_send = "type=ght&param=join&c=";
                    cout << "输入群聊ID : ";
                    string str_inp = "";
                    cin >> str_inp;
                    string str_inpu = str_send + str_inp;
/*
                    SEND(i_sock,str_inpu);

                    memset(buff,0,sizeof(buff));
                    int i_len = RECV(i_sock,buff);
                    string str_recv(buff);
                    */
                    string str_recv = request(i_sock,str_inpu);
                    
                    
                     string str_retmsg = GetValueBuUrl(str_recv, "msg");
                    if( GetValueBuUrl(str_recv, "code") == "0")
                    {
                        // p2p enter
                       // i_menu = 2;
                       cout << "code:" << GetValueBuUrl(str_recv, "code") << " : "<<  str_retmsg << endl;
                       //
                       m_gid = str_inp;
                       //recv thread  send thread
                        thread t_rec(&SocketClient::gchatRecv,this,i_sock);
                        thread t_send(&SocketClient::gchatSend,this,i_sock,m_gid);

                        cout << "thread start??" << endl;
                        t_rec.join();
                        t_send.join();

                    cout << "thread end??" << endl;
                        b_gchat = false;
                        
                    }else
                    {
                        cout <<  str_retmsg << endl;
                    }
                    break;
                };
                case 4:{
                    
                    string str_send = "type=get&param=q&c=" + m_gid;
                    /*
                    SEND(i_sock,str_send);

                    memset(buff,0,sizeof(buff));
                    int i_len = RECV(i_sock,buff);
                    */
                    string str_recv = request(i_sock,str_send);

                    cout << GetValueBuUrl(str_recv, "msg") << endl;

                    b_gchat = false;
                    i_menu = 1;
                    m_gid = "-1";
                    break;
                };
                default:{
                    cout << "input invaild!" << endl;
                    break;
                };
            }
        }
        else
        {
            cout << "invalid option." << endl;
            
        }
        
        //void(0);
    }

    close(i_sock);

}


void SocketClient::stop()
{
    b_run = false;
}

string SocketClient::request(int i_sock, string str_send)
{
    SEND(i_sock,str_send);
    char buff[MAXSIZE];
    memset(buff,0,sizeof(buff));
    recv(i_sock,buff,sizeof(buff),0);
    return string(buff);
}

void SocketClient::chatRecv(int con)
{
    char buffer[MAXSIZE];
    while(b_chat)
    {
        memset(buffer,0,sizeof(buffer));
        int siz = recv(con,buffer,sizeof(buffer),0);
        string str_tb(buffer);
       // cout << "chat Recv :" << buffer << endl;
        if( str_tb.find("exit") !=str_tb.npos  || siz <= 0)
        {
            cout << con << " 私聊接收线程关闭" << endl;
            b_chat = false;
            break;
        }

        cout << ":" << buffer << endl;
    }
}

void SocketClient::gchatRecv(int con)
{
    char buffer[MAXSIZE];
    while(b_gchat)
    {
        memset(buffer,0,sizeof(buffer));
        int siz = recv(con,buffer,sizeof(buffer),0);
        string str_tb(buffer);
        if( str_tb.find("exit") !=str_tb.npos || siz <= 0)
        {
            cout << con << " 群聊接收线程关闭" << endl;
            b_gchat = false;
            break;
        }

        cout << ":" << buffer << endl;
    }
}

void SocketClient::chatSend(int con,string username)
{
    char buffer[MAXSIZE];
    string str_mo = "type=chat&target="+ username +"&msg=";
    
    while(b_chat)
    {
        memset(buffer,0,sizeof(buffer));
        //cout << "#(exit) ";
        cin >> buffer;
        string str_tem =  str_mo + buffer;
        int siz = send(con,str_tem.c_str(),strlen(str_tem.c_str()),0);
        if( string(buffer) == "exit" ||  siz <= 0)
        {
            cout << con << " 私聊发送线程关闭" << endl;
            b_chat = false;
            break;
        }
        
    }
}

void SocketClient::gchatSend(int con,string gid)
{
    char buffer[MAXSIZE];
    string str_mo = "type=cgt&gid="+gid+"&msg=";
    
    while(b_gchat)
    {
        memset(buffer,0,sizeof(buffer));
        //cout << "#(exit) ";
        cin >> buffer;
        string str_tem =  str_mo + buffer;
        int siz = send(con,str_tem.c_str(),strlen(str_tem.c_str()),0);
        if( string(buffer) == "exit" ||  siz <= 0)
        {
            cout << con << " 群聊发送线程关闭" << endl;
            b_gchat = false;
            break;
        }
        
    }
}